<template>
  <div class="mapComponent">
    <div id="mapDiv"></div>
    <div class="box">
      <ul>
        <li v-for="(item, index) in layerList" :key="index" @click="setlayer(item.layerid, index)">
          <img :src="item.url" class="boximg" alt="" />
        </li>
      </ul>
    </div>
  </div>
</template>

<script>
import L from "leaflet";
import "leaflet/dist/leaflet.css";
import "@/components/map/leaflet-tilelayer-wmts.js"
import { BaseLayer } from "@/components/map/BaseLayler.js";
// import iconList from "@/utils/icon.js";

import weizhi from "@/assets/img/map/weizhi.png";
import layer0 from "@/assets/img/map/layer2.png";
import layer1 from "@/assets/img/map/layer3.png";
import layer2 from "@/assets/img/map/layer4.png";

// import { callApi } from "@/axios/index.ts";

// 引入 Lodash，控制防抖debounce和节流throttle
import throttle from "lodash/throttle";
import _ from "lodash";

// import { globalStore } from "@/store";
// const store = globalStore();

let map = null;
let markerItem = {}; // 标记图层对象
export default {
  data () {
    return {
      layerList: [ // 地图瓦片图层
        {
          layerid: 0,
          url: layer0,
        },
        {
          layerid: 2,
          url: layer2,
        },
        {
          layerid: 1,
          url: layer1,
        },
      ],
      currentLayerIndex: 1, // 当前显示的地图瓦片类型索引
      baseLayerMap: [], // 地图瓦片
      weizhi: { // 绘制信息
        typeLabel: "",
        position: "",
        icon: "",
      },
      zIndex: 1000, // 图层标记的层级

      layerMap: [], // 区域高亮图层组
      layerMapboundary: [], // 区域边界图层组
    };
  },
  mounted () {
    this.initMap();
  },
  methods: {
    // 初始化地图
    initMap () {
      console.log(map, "初始化地图");
      if (map) {

        // 遍历地图图层
        map.eachLayer((layer) => {
          layer.off();    // 移除该图层上的所有事件监听器
          layer.remove();  // 从地图中移除该图层
        });
      }
      const { // 引入地图瓦片
        OneStreetLayer,
        OneImageLayer,
        OneTopoMap,
        normalm,
        normala,
        imgm,
        imga,
        tera,
      } = BaseLayer;
      this.baseLayerMap = [OneTopoMap, new L.layerGroup([imgm, imga]), normalm]; // 地图瓦片组

      const layers = this.baseLayerMap[this.currentLayerIndex]; // 通过索引确定当前瓦片
      console.log(this.currentLayerIndex, layers, "this.currentLayerIndex");

      // 创建地图
      map = L.map("mapDiv", {
        minZoom: 6,
        maxZoom: 16,
        center: [29.898918, 119.476498],
        zoom: 6,
        layers: [layers],
        crs: L.CRS.EPSG4326,
        zoomControl: false,
        attributionControl: false,
        preferCanvas: true,
      });

      // 添加地图缩放事件
      map.on("zoomend", (e) => {
        console.log(e, "zoomend");
        this.mapZoomend(e);
      });
      // 添加地图移动事件
      map.on("moveend", (e) => {
        console.log(e, "moveend");
        this.mapRoveend(e);
      });
    },

    // 切换地图瓦片类型
    setlayer (index, key) {
      if (this.currentLayerIndex != index) {
        map.removeLayer(this.baseLayerMap[this.currentLayerIndex]);
        map.addLayer(this.baseLayerMap[index]);
        this.currentLayerIndex = index;
      }
    },

    // 通过经纬度绘制区域边界以及高亮图层
    drawMapBounds (data, color, fillColor, fillOpacity = 0.55, weight = 4) {
      let group = L.polygon(data, {
        color: color,
        weight: weight,
        fillOpacity: fillOpacity,
        fillColor: fillColor,
      }).addTo(map);

      this.layerMapboundary.push(group);
    },

    // geojson绘制外层区域边界
    drawMapBoundaries (data, color, fillColor, weight = 4) {
      let group = L.geoJSON(data, {
        color: color,
        weight: weight,
        fillOpacity: 0,
        fillColor: fillColor,
      }).addTo(map);
      this.layerMap.push(group);
      group?.getBounds() && map.fitBounds(group.getBounds()); // 将地图视图调整到图层边界
    },

    // geojson绘制内层区域边界
    drawMapBoundaries2 (data, color, fillColor, weight = 4) {
      let group = L.geoJSON(data, {
        color: color,
        weight: weight,
        fillOpacity: 0,
        fillColor: fillColor,
      }).addTo(map);
      this.layerMap.push(group);
    },

    // 移动到当前geojson位置
    flyToBounds (data) {
      console.log(data, "移动到当前geojson位置");
      let group = L.geoJSON(data);
      map.flyToBounds(group.getBounds());
    },

    // 绘制geojson
    mapdrawsurface (data, color, text, icon) {
      // 判断绘制的图层组是否存在,存则则删除之前的图层
      if (markerItem[text + "Group"]) {
        this.clearLayerGrounp(markerItem[text + "Group"], text);
        markerItem[text + "Group"] = null;
      }
      console.log(data, color, text, icon, "data, color, text,绘制地图");
      let that = this;
      // 绘制点位标识
      var customIcon = L.divIcon({
        html: `<div style='width:22px;height:22px'><img src='${icon}' style='width:22px;height:22px;'></img></div>`,
        iconSize: [22, 22],
        iconAnchor: [11, 11],
      });

      // 绘制geoJSON
      let group = L.geoJSON(data, {
        pointToLayer: function (feature, latlng) {
          if (latlng.lat && latlng.lng) {
            console.log(feature, latlng, "pointToLayer");
            // 存在点位图表帽子
            if (feature.properties.icon) {
              customIcon = L.divIcon({
                html: `<div style='width:22px;height:22px'><img src='${feature.properties.icon}' style='width:22px;height:22px;'></img></div>`,
                iconSize: [22, 22],
                iconAnchor: [11, 11],
              });
            }

            console.log();
            // 绘制点位标记
            var marker = L.marker(latlng, {
              icon: customIcon,  // 标记图表资源标识
              zIndexOffset: that.zIndex, // 设置最新图层堆叠顺序
            });
            return marker;
          }
        },
        // 在每个geojson要素上执行操作。例如，添加点击事件监听器和绑定弹出窗口
        onEachFeature: function (feature, layer) {
          if (feature.properties) {
            // 详细点位
            console.log(feature.properties.name, "feature.properties.name");

            // 判断是否点位内聚
            if (feature.properties.name) {
              // 添加点击事件监听器
              layer.on("click", function (e) {
                feature.typeLabel = data.name;
                that.$emit("marker-click", feature); // 在这里处理点击事件并传递数据
              });

              // 绑定弹出窗口
              layer
                .bindTooltip(feature.properties.name, {
                  className: "layerbindTooltip",
                  offset: [0, -11],
                  direction: "top",
                  permanent: map.getZoom() >= 12 ? true : false,
                })
                .openTooltip();

              // 添加移动事件监听器
              layer.on("mouseover", function (e) {
                layer
                  .bindTooltip(feature.properties.name, {
                    className: "layerbindTooltip",
                    offset: [0, -11],
                    direction: "top",
                    permanent: map.getZoom() >= 12 ? true : false,
                  })
                  .openTooltip();
              });

              // 绑定弹出窗口个元素并立即打开弹出窗口
              layer
                .bindPopup(feature.properties.name, {
                  className: "layerbindPopup",
                })
                .openPopup();
            } else {
              // 内聚点位
              console.log(feature.properties.total, "feature.properties.total");
              if (feature.properties.total > 1) {
                layer.bindTooltip(feature.properties.total, {
                  className: "layer-popup",
                  offset: [-1, -11],
                  direction: "top",
                  permanent: true,
                });
              } else {
              }
            }
          }
        },
        // 设置geojson特征的样式
        style: function () {
          return {
            color: color,
            weight: 4,
            fillOpacity: 0.3,
          };
        },
      }).addTo(map);

      ++this.zIndex;  // 自增图层堆叠顺序
      this.$emit("geojson-group", { name: text, group }); // 绘制成功触发父组件事件
      markerItem[text + "Group"] = group; // 记录绘制图层组，方便之后去除操作
    },

    // 删除高亮图层
    clearLayer () {
      console.log("删除高亮图层");
      // 删除区域高亮
      this.layerMap.forEach((item) => {
        map.removeLayer(item);
      });
      this.layerMap = [];
      // 删除区域边界
      this.layerMapboundary.forEach((item) => {
        map.removeLayer(item);
      });
      this.layerMapboundary = [];
    },

    // 删除指定图层
    clearLayerGrounp (layer, markerItemKey) {
      console.log(layer, markerItemKey, markerItem, "drawLayerGrounp");
      // 指定图层则删除,否则删除全部
      if (markerItemKey) {
        markerItem[markerItemKey + "Group"] &&
          map.removeLayer(markerItem[markerItemKey + "Group"]);
      } else if (layer) {
        map.removeLayer(layer);
      }
    },

    // 删除所有绘制图层
    stopDraw () {
      console.log(markerItem, "删除所有绘制图层");
      Object.keys(markerItem).forEach((key) => {
        markerItem[key].removeFrom(map);
      });
      markerItem = {}


    },

    // 缩放
    mapZoomend: _.debounce(function (e) {
      //缩放等级
      let scale = e.target.getZoom(); // 获取缩放级别
      let positions = { // 获取地图四个顶点位置
        lon1: map.getBounds().getNorthWest().lng,
        lat1: map.getBounds().getNorthWest().lat,
        lon2: map.getBounds().getNorthEast().lng,
        lat2: map.getBounds().getNorthEast().lat,
        lon3: map.getBounds().getSouthEast().lng,
        lat3: map.getBounds().getSouthEast().lat,
        lon4: map.getBounds().getSouthWest().lng,
        lat4: map.getBounds().getSouthWest().lat,
      };
      console.log("缩放", store.positions);
      this.weizhi.position = store.positions; // 获区绘制的地区位置
      this.weizhi.typeLabel =
        store.positions.typeLabel || this.weizhi.typeLabel; // 获取绘制的类型
      console.log(scale, this.weizhi, positions, "缩放");
      this.$emit("getZoomInformation", { scale, ...this.weizhi, positions }); // 触发父组件更新响应并地图
    }, 300),
    // 移动
    mapRoveend: _.debounce(function (e) {
      //缩放等级
      let scale = e.target.getZoom(); // 获取缩放级别
      let positions = { // 获取地图四个顶点位置
        lon1: map.getBounds().getNorthWest().lng,
        lat1: map.getBounds().getNorthWest().lat,
        lon2: map.getBounds().getNorthEast().lng,
        lat2: map.getBounds().getNorthEast().lat,
        lon3: map.getBounds().getSouthEast().lng,
        lat3: map.getBounds().getSouthEast().lat,
        lon4: map.getBounds().getSouthWest().lng,
        lat4: map.getBounds().getSouthWest().lat,
      };
      console.log("移动", store.positions);
      this.weizhi.position = store.positions;  // 获区绘制的地区位置
      this.weizhi.typeLabel =
        store.positions.typeLabel || this.weizhi.typeLabel; // 获取绘制的类型
      console.log(scale, this.weizhi, positions, "移动");
      this.$emit("getZoomInformation", { scale, ...this.weizhi, positions });  // 触发父组件更新响应并地图
    }, 300),


    // 获取绘制类别
    setTypeLabel (typeLabel) {
      this.weizhi.typeLabel = typeLabel;
    },

    // 聚合
    polymerization (typeLabel, position, icon) {
      console.log(map);
      this.weizhi.typeLabel = typeLabel;
      this.weizhi.position = position;
      this.weizhi.icon = icon;
      window.parent.postMessage({ message: 'sendIntoHomePage' }, '*'); // 优化iframe页面加载
    },

    // 移除地图事件
    removeEvent () {
      // map.off();
      let allEventListeners = map._events;
      console.log(map, allEventListeners, "移除");
      Object.keys(allEventListeners).forEach((eventName) => {
        if (eventName == "zoomend" || eventName == "moveend") {
          let event = allEventListeners[eventName];
          let lengthEvent = allEventListeners[eventName].length;
          map.off(eventName, event[lengthEvent - 1].fn);
        }
      });
    },

    // 获取屏幕经纬度
    getlatlon () {
      let positions = {
        lon1: map.getBounds().getNorthWest().lng,
        lat1: map.getBounds().getNorthWest().lat,
        lon2: map.getBounds().getNorthEast().lng,
        lat2: map.getBounds().getNorthEast().lat,
        lon3: map.getBounds().getSouthEast().lng,
        lat3: map.getBounds().getSouthEast().lat,
        lon4: map.getBounds().getSouthWest().lng,
        lat4: map.getBounds().getSouthWest().lat,
      };
      return positions;
    },

    // 获取地图此时缩放层级
    getZoom () {
      return map.getZoom();
    },
  },

  beforeUnmount () {
    // 若是地图存在则销毁地图
    if (map) {
      console.log(map, "beforeUnmount");
      map.eachLayer((layer) => {
        layer.off(); // 移除该图层上的所有事件监听器
        layer.remove(); // 从地图中移除该图层
      });
    }
  },
};
</script>

<style lang="scss" scoped>
.mapComponent,
#mapDiv {
  width: 100%;
  height: 100%;
}

.mapComponent {
  overflow: hidden;

  .content {
    width: 388px;
    height: 65vh;
    padding: 30px;
    background: url("@/assets/img/map/content.png") 0 0/100% 100% no-repeat;
  }
}

:deep().leaflet-div-icon {
  border: none;
  background: none;
}

:deep().leaflet-popup-tip-container {
  display: none;
}

.box {
  position: absolute;
  right: 25vw;
  bottom: 40px;
  z-index: 600;
}

.box ul {
  display: flex;
  justify-content: flex-center;
  border-radius: 32px;
  height: 64px;
  transition: all 0.3s;
}

.box ul li {
  position: relative;
  list-style-type: none;
  cursor: pointer;
  width: 10px;
  height: 64px;
  transition: all 0.5s;
  border-radius: 100%;
}

.box ul li:nth-of-type(3) {
  width: 64px;
}

:deep() .boximg {
  max-width: none !important;
}

.box ul:hover li {
  width: 64px;
  border-radius: 50%;
}

.box ul li:hover {
  width: 64px;
  border-radius: 50%;
}

:deep() .layer-popup {
  // width: 50px;
  // height: 50px;
  border: #417dfd 2px solid;
  border-radius: 15%;
}

:deep() .leaflet-tooltip-top:before {
  border-top-color: #417dfd;
}

:deep().leaflet-popup-content-wrapper,
.leaflet-popup-tip {
  border: 2px #417dfd solid;
}

:deep().leaflet-popup-content-wrapper {
  text-align: center;
  // padding: 0px;
}
</style>
<style lang="scss">
// 弹框样式
.layerbindTooltip {
  height: 40px;
  padding: 7px 14px 0 14px;
  display: flex;
  // align-items: center;
  justify-content: center;
  background: url("@/assets/img/map/popup2.png") 0 0/100% 100% no-repeat;
  border: none;
  box-shadow: none;
}
</style>